package com.intelligent.system.common.utils;

import com.intelligent.system.common.config.ThreadPoolConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程池工具类
 */
@Slf4j
@Component
public class ThreadPoolUtils {
    private ThreadPoolExecutor executor;
    private final ThreadPoolConfig config;
    
    // 拒绝策略
    private static final RejectedExecutionHandler REJECTED_HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();

    public ThreadPoolUtils(ThreadPoolConfig config) {
        this.config = config;
    }

    @PostConstruct
    public void init() {
        // 如果没有配置核心线程数，则使用CPU核心数 + 1
        int corePoolSize = config.getCorePoolSize() != null ? 
                config.getCorePoolSize() : 
                Runtime.getRuntime().availableProcessors() + 1;
        
        // 如果没有配置最大线程数，则使用核心线程数 * 2
        int maxPoolSize = config.getMaxPoolSize() != null ? 
                config.getMaxPoolSize() : 
                corePoolSize * 2;
        
        // 如果没有配置队列容量，则使用默认值1000
        int queueCapacity = config.getQueueCapacity() != null ? 
                config.getQueueCapacity() : 
                1000;
        
        // 如果没有配置线程空闲时间，则使用默认值60秒
        long keepAliveTime = config.getKeepAliveTime() != null ? 
                config.getKeepAliveTime() : 
                60L;

        executor = new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(queueCapacity),
                new NamedThreadFactory("common-pool"),
                REJECTED_HANDLER
        );
        
        log.info("Thread pool initialized with core size: {}, max size: {}, queue capacity: {}, keep alive time: {}s",
                corePoolSize, maxPoolSize, queueCapacity, keepAliveTime);
    }

    @PreDestroy
    public void destroy() {
        if (executor != null) {
            executor.shutdown();
            try {
                if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
                Thread.currentThread().interrupt();
            }
            log.info("线程池关闭完成");
        }
    }

    /**
     * 执行任务
     *
     * @param task 任务
     */
    public void execute(Runnable task) {
        executor.execute(task);
    }

    /**
     * 提交任务
     *
     * @param task 任务
     * @return Future对象
     */
    public <T> Future<T> submit(Callable<T> task) {
        return executor.submit(task);
    }

    /**
     * 提交任务
     *
     * @param task 任务
     * @return Future对象
     */
    public Future<?> submit(Runnable task) {
        return executor.submit(task);
    }

    /**
     * 批量执行任务
     *
     * @param tasks 任务列表
     * @return Future列表
     */
    public <T> List<Future<T>> invokeAll(List<Callable<T>> tasks) throws InterruptedException {
        return executor.invokeAll(tasks);
    }

    /**
     * 批量执行任务（带超时）
     *
     * @param tasks 任务列表
     * @param timeout 超时时间
     * @param unit 时间单位
     * @return Future列表
     */
    public <T> List<Future<T>> invokeAll(List<Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
        return executor.invokeAll(tasks, timeout, unit);
    }

    /**
     * 获取线程池状态
     */
    public ThreadPoolStatus getStatus() {
        return new ThreadPoolStatus(
                executor.getPoolSize(),
                executor.getActiveCount(),
                executor.getCompletedTaskCount(),
                executor.getQueue().size(),
                executor.getTaskCount()
        );
    }

    /**
     * 线程池状态信息
     */
    @lombok.Data
    public static class ThreadPoolStatus {
        private final int poolSize;        // 当前线程数
        private final int activeCount;     // 活跃线程数
        private final long completedCount; // 已完成任务数
        private final int queueSize;       // 队列中任务数
        private final long taskCount;      // 总任务数

        public ThreadPoolStatus(int poolSize, int activeCount, long completedCount, int queueSize, long taskCount) {
            this.poolSize = poolSize;
            this.activeCount = activeCount;
            this.completedCount = completedCount;
            this.queueSize = queueSize;
            this.taskCount = taskCount;
        }
    }

    /**
     * 自定义线程工厂
     */
    private static class NamedThreadFactory implements ThreadFactory {
        private final AtomicInteger sequence = new AtomicInteger(1);
        private final String prefix;

        public NamedThreadFactory(String prefix) {
            this.prefix = prefix;
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName(prefix + "-" + sequence.getAndIncrement());
            thread.setDaemon(false);
            return thread;
        }
    }
} 